package com.example.vue.jwt.interceptor;

import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.example.vue.account.mapper.AccountMapper;
import com.example.vue.comm.domain.ResultData;
import com.example.vue.comm.util.WebUtil;
import com.example.vue.sys.mapper.SysMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        ResultData data = ResultData.success(null);

        // 构建查询参数
        Map<String, Object> params = new HashMap<>();
        String uri = request.getRequestURI();
        String method = request.getMethod();
        params.put("reqUrl", WebUtil.uriToReqUrlParams(uri));
        params.put("reqType", WebUtil.methodToReqTypeParams(method));
        // 1.获取当前资源信息
        Map<String, Object> authMenu = sysMenuMapper.authMenu(params);
        if (Objects.isNull(authMenu)) {  // 暂时做 没有查询到的请求资源都不做处理
            return true;
        }
        // 2.查看资源信息是否需要被认证
        int authentication = (int) authMenu.get("authentication");
        if (authentication == 0) {   // 不需要认证
            return true;
        }
        // 3.查看当前的token信息
        String token = request.getHeader("token");
        // 4.token信息是否过期或者非法
        String accountNo = JWT.decode(token).getClaim("accountNo").asString();
        params.put("accountNo", accountNo);
        // 5.从token信息中拿到用户信息
        Map<String, Object> accountInfo = accountMapper.queryAccount(params);
        if (Objects.isNull(accountInfo)) {    // 告诉浏览器返回到登录页面处理
            data.setCode(401);  // 没有访问该api的权限信息
            data.setMessage("无权限信息,当前用户token过期");
            String jsonStr = JSONUtil.toJsonStr(data);
            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            response.getWriter().print(jsonStr);
            response.flushBuffer();
            return false;
        }
        // 6.查看当前用户是否具有当前资源信息
        params.put("menuNo", authMenu.get("menuNo"));
        Map<String, Object> authMenuInfo = accountMapper.queryAuthMenu(params);
        if (Objects.isNull(authMenuInfo)) {   // 如果不具备当前资源
            data.setCode(401);  // 没有访问该api的权限信息
            data.setMessage("无权限信息,不具备当前资源访问");
            String jsonStr = JSONUtil.toJsonStr(data);
            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            response.getWriter().print(jsonStr);
            response.flushBuffer();
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }


}